package com.zt.teacher.netty;

import com.zt.common.utils.SslUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;

/**
 * description:
 * author:zt
 * date:2022-01-17
 */
@Component
public class NettyChannelInitializer extends ChannelInitializer {

    @Autowired
    private MyTextWebSocketFrameHandler myTextWebSocketFrameHandler;

    @Override
    protected void initChannel(Channel channel) throws Exception {
        ChannelPipeline pipeline = channel.pipeline();
        //基于http协议，所以使用http的编码和解码器
        pipeline.addLast(new HttpServerCodec());
        //是以块的形式写，添加ChunkedWriteHandler处理器
        pipeline.addLast(new ChunkedWriteHandler());
                            /*
                            http数据在传输时是分段的，HttpObjectAggregator处理器，将多个段聚合
                            这也是为什么浏览器在发送大量数据时，会发出多次http请求
                             */
        pipeline.addLast(new HttpObjectAggregator(8192));

                            /*
                                websocket它的数据是以 帧（frame） 的形式传输
                                浏览器请求时 url是 ws://localhost:{port}/ws
                                WebSocketServerProtocolHandler的核心功能是将http协议升级为ws协议，保持长连接
                             */
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

        //自定义的业务逻辑处理器
        pipeline.addLast(myTextWebSocketFrameHandler);

        //为要支持wss所需处理
//        SSLContext sslContext = SslUtil.createSSLContext("C:\\Users\\85729\\IdeaProjects\\study\\teacher\\src\\main\\resources\\6669541_murielndzt.top.pfx",
//                "lhYHpuH7");
        SSLContext sslContext = SslUtil.createSSLContext("/root/6669541_murielndzt.top.pfx", "lhYHpuH7");
        SSLEngine sslEngine = sslContext.createSSLEngine();
        sslEngine.setUseClientMode(false);
        sslEngine.setNeedClientAuth(false);
        // 需把SslHandler添加在第一位
        pipeline.addFirst("ssl", new SslHandler(sslEngine));
    }
}
